/**
Copyright: Copyright (c) 2017-2019 Andrey Penechko.
License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0).
Authors: Andrey Penechko.
*/
module be.asmtest.imul;

import be.asmtest.utils;

void testImul(CodegenTester tester)
{
	// Imul reg16, reg16
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.imulw(Register.min, regB);
	tester.assertHexAndReset("660FAFC0660FAFC8660FAFD0660FAFD8660FAFE0660FAFE8660FAFF0660FAFF866440FAFC066440FAFC866440FAFD066440FAFD866440FAFE066440FAFE866440FAFF066440FAFF8660FAFC0660FAFC1660FAFC2660FAFC3660FAFC4660FAFC5660FAFC6660FAFC766410FAFC066410FAFC166410FAFC266410FAFC366410FAFC466410FAFC566410FAFC666410FAFC7");

	// Imul reg32, reg32
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.imuld(Register.min, regB);
	tester.assertHexAndReset("0FAFC00FAFC80FAFD00FAFD80FAFE00FAFE80FAFF00FAFF8440FAFC0440FAFC8440FAFD0440FAFD8440FAFE0440FAFE8440FAFF0440FAFF80FAFC00FAFC10FAFC20FAFC30FAFC40FAFC50FAFC60FAFC7410FAFC0410FAFC1410FAFC2410FAFC3410FAFC4410FAFC5410FAFC6410FAFC7");

	// Imul reg64, reg64
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(regA, Register.min);
	foreach (Register regB; Register.min..RegisterMax) tester.imulq(Register.min, regB);
	tester.assertHexAndReset("480FAFC0480FAFC8480FAFD0480FAFD8480FAFE0480FAFE8480FAFF0480FAFF84C0FAFC04C0FAFC84C0FAFD04C0FAFD84C0FAFE04C0FAFE84C0FAFF04C0FAFF8480FAFC0480FAFC1480FAFC2480FAFC3480FAFC4480FAFC5480FAFC6480FAFC7490FAFC0490FAFC1490FAFC2490FAFC3490FAFC4490FAFC5490FAFC6490FAFC7");

	// Imul reg16, mem16
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(Register.min, memAddrBase(regA));
	tester.assertHexAndReset("660FAF00660FAF01660FAF02660FAF03660FAF0424660FAF4500660FAF06660FAF0766410FAF0066410FAF0166410FAF0266410FAF0366410FAF042466410FAF450066410FAF0666410FAF07");

	// Imul reg32, mem32
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(Register.min, memAddrBase(regA));
	tester.assertHexAndReset("0FAF000FAF010FAF020FAF030FAF04240FAF45000FAF060FAF07410FAF00410FAF01410FAF02410FAF03410FAF0424410FAF4500410FAF06410FAF07");

	// Imul reg64, mem64
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(Register.min, memAddrBase(regA));
	tester.assertHexAndReset("480FAF00480FAF01480FAF02480FAF03480FAF0424480FAF4500480FAF06480FAF07490FAF00490FAF01490FAF02490FAF03490FAF0424490FAF4500490FAF06490FAF07");


	// Imul reg16, reg16, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(regA, Register.min, Imm8(0x24));
	foreach (Register regB; Register.min..RegisterMax) tester.imulw(Register.min, regB, Imm8(0x24));
	tester.assertHexAndReset("666BC024666BC824666BD024666BD824666BE024666BE824666BF024666BF82466446BC02466446BC82466446BD02466446BD82466446BE02466446BE82466446BF02466446BF824666BC024666BC124666BC224666BC324666BC424666BC524666BC624666BC72466416BC02466416BC12466416BC22466416BC32466416BC42466416BC52466416BC62466416BC724");

	// Imul reg32, reg32, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(regA, Register.min, Imm8(0x24));
	foreach (Register regB; Register.min..RegisterMax) tester.imuld(Register.min, regB, Imm8(0x24));
	tester.assertHexAndReset("6BC0246BC8246BD0246BD8246BE0246BE8246BF0246BF824446BC024446BC824446BD024446BD824446BE024446BE824446BF024446BF8246BC0246BC1246BC2246BC3246BC4246BC5246BC6246BC724416BC024416BC124416BC224416BC324416BC424416BC524416BC624416BC724");

	// Imul reg64, reg64, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(regA, Register.min, Imm8(0x24));
	foreach (Register regB; Register.min..RegisterMax) tester.imulq(Register.min, regB, Imm8(0x24));
	tester.assertHexAndReset("486BC024486BC824486BD024486BD824486BE024486BE824486BF024486BF8244C6BC0244C6BC8244C6BD0244C6BD8244C6BE0244C6BE8244C6BF0244C6BF824486BC024486BC124486BC224486BC324486BC424486BC524486BC624486BC724496BC024496BC124496BC224496BC324496BC424496BC524496BC624496BC724");

	// Imul reg16, reg16, imm16
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(regA, Register.min, Imm16(0x2436));
	foreach (Register regB; Register.min..RegisterMax) tester.imulw(Register.min, regB, Imm16(0x2436));
	tester.assertHexAndReset("6669C036246669C836246669D036246669D836246669E036246669E836246669F036246669F83624664469C03624664469C83624664469D03624664469D83624664469E03624664469E83624664469F03624664469F836246669C036246669C136246669C236246669C336246669C436246669C536246669C636246669C73624664169C03624664169C13624664169C23624664169C33624664169C43624664169C53624664169C63624664169C73624");

	// Imul reg32, reg32, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(regA, Register.min, Imm32(0x24364758));
	foreach (Register regB; Register.min..RegisterMax) tester.imuld(Register.min, regB, Imm32(0x24364758));
	tester.assertHexAndReset("69C05847362469C85847362469D05847362469D85847362469E05847362469E85847362469F05847362469F8584736244469C0584736244469C8584736244469D0584736244469D8584736244469E0584736244469E8584736244469F0584736244469F85847362469C05847362469C15847362469C25847362469C35847362469C45847362469C55847362469C65847362469C7584736244169C0584736244169C1584736244169C2584736244169C3584736244169C4584736244169C5584736244169C6584736244169C758473624");

	// Imul reg64, reg64, imm32
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(regA, Register.min, Imm32(0x24364758));
	foreach (Register regB; Register.min..RegisterMax) tester.imulq(Register.min, regB, Imm32(0x24364758));
	tester.assertHexAndReset("4869C0584736244869C8584736244869D0584736244869D8584736244869E0584736244869E8584736244869F0584736244869F8584736244C69C0584736244C69C8584736244C69D0584736244C69D8584736244C69E0584736244C69E8584736244C69F0584736244C69F8584736244869C0584736244869C1584736244869C2584736244869C3584736244869C4584736244869C5584736244869C6584736244869C7584736244969C0584736244969C1584736244969C2584736244969C3584736244969C4584736244969C5584736244969C6584736244969C758473624");


	// Imul reg16, mem16, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulw(Register.min, memAddrBase(regA), Imm8(0x24));
	tester.assertHexAndReset("666B0024666B0124666B0224666B0324666B042424666B450024666B0624666B072466416B002466416B012466416B022466416B032466416B04242466416B45002466416B062466416B0724");

	// Imul reg32, mem32, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imuld(Register.min, memAddrBase(regA), Imm8(0x24));
	tester.assertHexAndReset("6B00246B01246B02246B03246B0424246B4500246B06246B0724416B0024416B0124416B0224416B0324416B042424416B450024416B0624416B0724");

	// Imul reg64, mem64, imm8
	foreach (Register regA; Register.min..RegisterMax) tester.imulq(Register.min, memAddrBase(regA), Imm8(0x24));
	tester.assertHexAndReset("486B0024486B0124486B0224486B0324486B042424486B450024486B0624486B0724496B0024496B0124496B0224496B0324496B042424496B450024496B0624496B0724");
}
